package admin

import (
	j_log "config-client-v1/init/j-log"
	"config-client-v1/model"
	"config-client-v1/utils/tools"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"strconv"
)

const LOGIN_KEY = "@go"

func GetUserToken(ctx *gin.Context) model.UserToken {
	val, _ := ctx.Get("userToken")
	userToken, _ := val.(model.UserToken)
	return userToken
}

func FillFrameID(list []*model.FrameItem, frameID int) {
	for _, row := range list {
		row.FrameID = frameID
	}
}

func GetChangeItems(list []*model.FrameItem, listOld []*model.FrameItem) (listUpdate []*model.FrameItem, listInsert []*model.FrameItem, idsDelete []int) {
	listUpdate = make([]*model.FrameItem, 0)
	listInsert = make([]*model.FrameItem, 0)
	idsDelete = make([]int, 0)
	newIDMap := make(map[int]bool)
	oldIDMap := make(map[int]bool)
	now := tools.GetNow()
	for _, rowNew := range list {
		newIDMap[rowNew.ID] = true
	}
	for _, rowOld := range listOld {
		oldIDMap[rowOld.ID] = true
	}
	for _, rowNew := range list {
		if !oldIDMap[rowNew.ID] {
			rowNew.CreateTime = &now
			rowNew.UpdateTime = &now
			listInsert = append(listInsert, rowNew)
		} else {
			rowNew.UpdateTime = &now
			listUpdate = append(listUpdate, rowNew)
		}
	}
	for _, rowOld := range listOld {
		if !newIDMap[rowOld.ID] {
			idsDelete = append(idsDelete, rowOld.ID)
		}
	}
	return
}

func GetFrameIdByType(frameType string) (ids []int) {
	ids = make([]int, 0)
	_ = model.DB.Model(&model.Frame{}).Where("frame_type = ?", frameType).Pluck("id", &ids).Error
	return
}

// 切片变量作为【指针地址】传入函数， 但是如果切片在函数内不断扩容，传入的【指针地址】会发生改变，所以使用方式如下面两种
/*--- 切片类型的使用方法 一 切片变量指针传入 ---*/
func putFSDownloadModuleAPI(fse *model.FSEquip, list *[]*DownloadApi, moduleType string) {
	for _, row := range fse.FSModule {
		if row.ModuleType == moduleType {
			moduleNumber, _ := strconv.Atoi(row.Code3)
			*list = append(*list, &DownloadApi{Name: moduleType + "下载", Detail: fmt.Sprintf("%s%s下载", moduleType, row.Code3), Url: "admin/fs/module_download", Params: map[string]interface{}{
				"fs_id":         fse.ID,
				"module_type":   row.ModuleType,
				"module_number": moduleNumber,
			}})
		}
	}
}

func putFSDownloadModelAPI(fse *model.FSEquip, list *[]*DownloadApi, moduleType string) {
	for _, row := range fse.FSModule {
		if row.ModuleType == moduleType {
			moduleNumber, _ := strconv.Atoi(row.Code3)
			*list = append(*list, &DownloadApi{Name: moduleType + "模型下载", Detail: fmt.Sprintf("%s%s下载", moduleType, row.Code3), Url: "admin/fs/model_download", Params: map[string]interface{}{
				"fs_id":         fse.ID,
				"module_type":   row.ModuleType,
				"module_number": moduleNumber,
			}})
		}
	}
}

func putFSModuleUploadAPI(fse *model.FSEquip, list *[]*DownloadApi, moduleType string, moduleQuantity uint8) {
	for i := 1; i <= int(moduleQuantity); i++ {
		*list = append(*list, &DownloadApi{Name: moduleType + "上载", Detail: fmt.Sprintf("%s%d模型上载", moduleType, i), Url: "admin/fs/module_upload",
			Params: map[string]interface{}{
				"fs_id":         fse.ID,
				"module_type":   moduleType,
				"module_number": i,
			}})
	}
}

func putFSModelUploadAPI(fse *model.FSEquip, list *[]*DownloadApi, moduleType string, moduleQuantity uint8) {
	for i := 1; i <= int(moduleQuantity); i++ {
		*list = append(*list, &DownloadApi{Name: moduleType + "模型上载", Detail: fmt.Sprintf("%s%d模型上载", moduleType, i), Url: "admin/fs/model_upload",
			Params: map[string]interface{}{
				"fs_id":         fse.ID,
				"module_type":   moduleType,
				"module_number": i,
			}})
	}
}

func validateDataPart0604(fse *model.FSEquip, list []*model.DataPart0604) (err error) {
	for _, row := range list {
		v, ok1 := model.AllowCmd0604Code[row.ModuleType]
		if !ok1 {
			err = errors.New("无效的参数type:" + row.ModuleType)
			return
		}
		code1 := fse.Code1
		code2 := ""
		code3 := fmt.Sprintf("%02d", row.Addr)
		code4 := fmt.Sprintf("%03d", row.Number)
		key := ""
		row.TypeValue = v
		switch row.ModuleType {
		case "AI":
			code2 = "00"
			key = fmt.Sprintf("%s-%s-%s-%s", code1, code2, code3, code4)
		case "AQ":
			code2 = "01"
			key = fmt.Sprintf("%s-%s-%s-%s", code1, code2, code3, code4)
		case "DQ":
			code2 = "03"
			key = fmt.Sprintf("%s-%s-%s-%s", code1, code2, code3, code4)
		case "Other":
			code2 = "04"
			key = fmt.Sprintf("%s-%s-%s-%s", code1, code2, code3, code4)
		case "泵组电磁阀":
			code2 = "05"
			matched := false
			for _, module := range fse.FSModule {
				if module.Code1 == code1 && module.Code2 == code2 && module.Code3 == code3 {
					content := &model.BengzuModel{}
					err = json.Unmarshal([]byte(module.JsonDetail), content)
					if err != nil {
						j_log.LogError([]interface{}{"json.Unmarshal error(泵组电磁阀)", err.Error()})
						return
					}
					switch row.Number {
					case 1:
						key = content.BengzuStartControl
					case 2:
						key = content.BengzuStopControl
					case 3:
						key = content.Liansuo
					default:
						err = errors.New("泵组电磁阀值序号可选范围为[1,2,3]")
						return
					}
					matched = true
					break
				}
			}
			if !matched {
				err = errors.New(fmt.Sprintf("设备【%s】中未找到【%s - %02d】", fse.Name, row.ModuleType, row.Number))
				return
			}
		case "增压泵电磁阀":
			code2 = "06"
			matched := false
			for _, module := range fse.FSModule {
				if module.Code1 == code1 && module.Code2 == code2 && module.Code3 == code3 {
					content := &model.ZengyaModel{}
					err = json.Unmarshal([]byte(module.JsonDetail), content)
					if err != nil {
						j_log.LogError([]interface{}{"json.Unmarshal error(增压泵电磁阀)", err.Error()})
						return
					}
					switch row.Number {
					case 1:
						key = content.Liansuo
					default:
						err = errors.New("增压泵电磁阀值序号可选范围为[1]")
						return
					}
					matched = true
					break
				}
			}
			if !matched {
				err = errors.New(fmt.Sprintf("设备【%s】中未找到【%s - %02d】", fse.Name, row.ModuleType, row.Number))
				return
			}
		case "压力电磁阀":
			code2 = "08"
			matched := false
			for _, module := range fse.FSModule {
				if module.Code1 == code1 && module.Code2 == code2 && module.Code3 == code3 {
					content := &model.PressureSVModel{}
					err = json.Unmarshal([]byte(module.JsonDetail), content)
					if err != nil {
						j_log.LogError([]interface{}{"json.Unmarshal error(压力电磁阀)", err.Error()})
						return
					}
					switch row.Number {
					case 1:
						key = content.Liansuo
					default:
						err = errors.New("压力电磁阀值序号可选范围为[1]")
						return
					}
					matched = true
					break
				}
			}
			if !matched {
				err = errors.New(fmt.Sprintf("【%s】中未找到【%s - %02d】", fse.Name, row.ModuleType, row.Number))
				return
			}
		default:
			err = errors.New("无效的参数module_type~" + row.ModuleType)
			return
		}
		_, ok := model.VariablesMap.Get(key)
		if !ok {
			err = errors.New(fmt.Sprintf("【%s - %s - %02d】对应的变量%s不存在", fse.Name, row.ModuleType, row.Number, key))
			return
		}
	}
	return
}

func ProjectCreatedHook(projectID int) (err error) {
	listTmp := make([]*model.AlertTypeDefault, 0)
	err = model.DB.Find(&listTmp).Error
	if err != nil {
		return
	}
	now := tools.GetNow()
	list := make([]*model.AlertType, 0)
	for _, item := range listTmp {
		list = append(list, &model.AlertType{
			ProjectID:  projectID,
			Const:      item.Const,
			T1:         item.T1,
			T2:         item.T2,
			Level:      item.Level,
			Audio:      item.Audio,
			Color:      item.Color,
			Desc:       item.Desc,
			CreateTime: &now,
			UpdateTime: &now,
		})
	}
	err = model.DB.Create(&list).Error
	if err != nil {
		return
	}
	return
}

//func UpdateMemoryDataFSEModule(moduleID int) (err error) {
//	fse := &model.FSModule{}
//	err = model.DB.Where("id = ?", moduleID).Limit(1).First(fse).Error
//	if err != nil {
//		return
//	}
//	fseTmp, ok := model.RunningFSMap.Get(fse.ID)
//	if ok {
//		fseTmp.Name = fse.Name
//		for _,module := range fseTmp.FSModule {
//			module
//		}
//
//	}
//	return nil
//}
